package com.yanqu.road.server;

import com.yanqu.road.dao.db.DBManager;
import com.yanqu.road.NettyMgr;
import com.yanqu.road.connect.ServerLinkControl;
import com.yanqu.road.server.handle.ChannelServerHandler;
import com.yanqu.road.server.channelserver.webservice.ChannelWebServiceHelper;
import com.yanqu.road.utils.net.ChannelNetConfigHelper;
import com.yanqu.road.utils.ConfigHelper;
import com.yanqu.road.utils.net.ServerNetConfig;
import com.yanqu.road.utils.net.ServerNetConfigHelper;
import com.yanqu.road.utils.executor.ScheduledThreadPoolHelper;
import com.yanqu.road.utils.executor.GeneralThreadFactory;
import com.yanqu.road.utils.monitor.MonitorHelper;
import io.netty.channel.ChannelHandler;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;

public class ChannelBaseServer extends TempServer {

    static Logger logger = LogManager.getLogger(Class.class.getName());

    protected static ChannelBaseServer channelBaseServer;

    private static ExecutorService serverCommandExecutor = null;

    protected boolean isStop;

    public ChannelBaseServer() {

    }

    public static ChannelBaseServer getInstance() {
        return channelBaseServer;
    }

    public boolean isStop() {
        return isStop;
    }

    public void setStop(boolean stop) {
        this.isStop = stop;
    }

    public static ExecutorService getServerCommandExecutor() {
        return serverCommandExecutor;
    }

    public static void setServerCommandExecutor(ExecutorService serverCommandExecutor) {
        ChannelBaseServer.serverCommandExecutor = serverCommandExecutor;
    }

    public boolean start(int serverType, String serverName) {
        // 启动定时器线程池
        int corePoolSize = Runtime.getRuntime().availableProcessors() * 2;
        corePoolSize = Math.min(8, Math.max(4, corePoolSize));
        timerScheduledExecutorService = ScheduledThreadPoolHelper.createGameScheduledThreadPoolExecutor(corePoolSize, "timer-" + serverName);

        // 调整实际使用的消息处理线程数量
        serverCommandExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 4,
                new GeneralThreadFactory(serverName + "-cmd"));

        MonitorHelper.monitorPool(serverName + "-cmd", (ThreadPoolExecutor) serverCommandExecutor);


        if (!super.start()) {
            return false;
        }

        if (!initGameModule(com.yanqu.road.thread.ThreadPoolHelper.init(), "load thread pool")) {
            return false;
        }

        if (!initGameModule(DBManager.initConfig(ConfigHelper.getValue("db.path")), "load center db")) {
            return false;
        }


        if (!initGameModule(DBManager.initChannelDbConfig(serverType), "load channel db")) {
            return false;
        }

        if (!initGameModule(initNetty(new ChannelServerHandler(), serverType), "load netty")) {
            return false;
        }

        if (!initGameModule(ChannelWebServiceHelper.getInstance().start(serverType), "load channelWebService")) {
            return false;
        }

        logger.info("current path:" + System.getProperty("user.dir"));
        return true;
    }

    @Override
    protected boolean initNetWorkConfig() {
        try {
            return ChannelNetConfigHelper.init(DBManager.getChannelNetConfigFromDb());

        } catch (Exception e) {
            logger.error("init net config error", e);
        }
        return false;
    }

    @Override
    protected boolean initNetty(ChannelHandler handler, int type) {
        ServerNetConfig netXml = ChannelNetConfigHelper.getNetConfigXml(type, 0);
        if (netXml == null) {
            logger.error("can not found connection config info, server will start failed.");
            return false;
        }
        boolean result = NettyMgr.start(netXml.getPort(), handler);
        if (!result) {
            return false;
        }
        logger.info("netty star port: {}", netXml.getPort());

        ServerLinkControl.initServerLinkControl(ServerNetConfigHelper.getAgentCount());

        return true;
    }

    @Override
    public List<TempMgr> getMgrList() {
        return null;
    }
}
